From: "Kristian H. Kristensen" <hoegsb...@chromium.org>

This adds support for the new DRM_IOCTL_MODE_GETPLANE2 ioctl. For older
kernels drmModeGetPlane2() falls back to DRM_IOCTL_MODE_GETPLANE and
return the new, bigger drmModePlaneRec, reporting 0 modifiers.

BUG=chrome-os-partner:56407
TEST=modetest with next commit reports modifiers

Change-Id: I9cf9979c0b72933bad661fd03b9beebb36120dfd
---
 include/drm/drm.h      |  1 +
 include/drm/drm_mode.h | 27 +++++++++++++++++++++++++++
 xf86drmMode.c          | 49 ++++++++++++++++++++++++++++++++++++++++++++-----
 xf86drmMode.h          |  4 ++++
 4 files changed, 76 insertions(+), 5 deletions(-)

diff --git a/include/drm/drm.h b/include/drm/drm.h
index f6fd5c2..09d4262 100644
--- a/include/drm/drm.h
+++ b/include/drm/drm.h
@@ -799,6 +799,7 @@ extern "C" {
 #define DRM_IOCTL_MODE_DESTROY_DUMB    DRM_IOWR(0xB4, struct 
drm_mode_destroy_dumb)
 #define DRM_IOCTL_MODE_GETPLANERESOURCES DRM_IOWR(0xB5, struct 
drm_mode_get_plane_res)
 #define DRM_IOCTL_MODE_GETPLANE        DRM_IOWR(0xB6, struct 
drm_mode_get_plane)
+#define DRM_IOCTL_MODE_GETPLANE2       DRM_IOWR(0xB6, struct 
drm_mode_get_plane2)
 #define DRM_IOCTL_MODE_SETPLANE        DRM_IOWR(0xB7, struct 
drm_mode_set_plane)
 #define DRM_IOCTL_MODE_ADDFB2          DRM_IOWR(0xB8, struct drm_mode_fb_cmd2)
 #define DRM_IOCTL_MODE_OBJ_GETPROPERTIES       DRM_IOWR(0xB9, struct 
drm_mode_obj_get_properties)
diff --git a/include/drm/drm_mode.h b/include/drm/drm_mode.h
index df0e350..ce773fa 100644
--- a/include/drm/drm_mode.h
+++ b/include/drm/drm_mode.h
@@ -193,6 +193,33 @@ struct drm_mode_get_plane {
        __u64 format_type_ptr;
 };

+struct drm_format_modifier {
+       /* Bitmask of formats in get_plane format list this info
+        * applies to. */
+       __u64 formats;
+
+       /* This modifier can be used with the format for this plane. */
+       __u64 modifier;
+};
+
+struct drm_mode_get_plane2 {
+       __u32 plane_id;
+
+       __u32 crtc_id;
+       __u32 fb_id;
+
+       __u32 possible_crtcs;
+       __u32 gamma_size;
+
+       __u32 count_format_types;
+       __u64 format_type_ptr;
+
+       /* New in v2 */
+       __u32 count_format_modifiers;
+       __u32 flags;
+       __u64 format_modifier_ptr;
+};
+
 struct drm_mode_get_plane_res {
        __u64 plane_id_ptr;
        __u32 count_planes;
diff --git a/xf86drmMode.c b/xf86drmMode.c
index fb22f68..298d502 100644
--- a/xf86drmMode.c
+++ b/xf86drmMode.c
@@ -990,15 +990,15 @@ int drmModeSetPlane(int fd, uint32_t plane_id, uint32_t 
crtc_id,
        return DRM_IOCTL(fd, DRM_IOCTL_MODE_SETPLANE, &s);
 }

-drmModePlanePtr drmModeGetPlane(int fd, uint32_t plane_id)
+static drmModePlanePtr get_plane(unsigned long cmd, int fd, uint32_t plane_id)
 {
-       struct drm_mode_get_plane ovr, counts;
+       struct drm_mode_get_plane2 ovr, counts;
        drmModePlanePtr r = 0;

 retry:
        memclear(ovr);
        ovr.plane_id = plane_id;
-       if (drmIoctl(fd, DRM_IOCTL_MODE_GETPLANE, &ovr))
+       if (drmIoctl(fd, cmd, &ovr))
                return 0;

        counts = ovr;
@@ -1010,11 +1010,21 @@ retry:
                        goto err_allocs;
        }

-       if (drmIoctl(fd, DRM_IOCTL_MODE_GETPLANE, &ovr))
+       if (ovr.count_format_modifiers) {
+               ovr.format_modifier_ptr =
+                       VOID2U64(drmMalloc(ovr.count_format_modifiers *
+                                          sizeof(struct drm_format_modifier)));
+               if (!ovr.format_modifier_ptr)
+                       goto err_allocs;
+       }
+
+       if (drmIoctl(fd, cmd, &ovr))
                goto err_allocs;

-       if (counts.count_format_types < ovr.count_format_types) {
+       if (counts.count_format_types < ovr.count_format_types ||
+           counts.count_format_modifiers < ovr.count_format_modifiers) {
                drmFree(U642VOID(ovr.format_type_ptr));
+               drmFree(U642VOID(ovr.format_modifier_ptr));
                goto retry;
        }

@@ -1022,6 +1032,7 @@ retry:
                goto err_allocs;

        r->count_formats = ovr.count_format_types;
+       r->count_format_modifiers = ovr.count_format_modifiers;
        r->plane_id = ovr.plane_id;
        r->crtc_id = ovr.crtc_id;
        r->fb_id = ovr.fb_id;
@@ -1033,20 +1044,48 @@ retry:
                drmFree(r->formats);
                drmFree(r);
                r = 0;
+               goto err_allocs;
+       }
+
+       r->format_modifiers =
+               drmAllocCpy(U642VOID(ovr.format_modifier_ptr),
+                           ovr.count_format_modifiers,
+                           sizeof(struct drm_format_modifier));
+       if (ovr.count_format_modifiers && !r->format_modifiers) {
+               drmFree(r->formats);
+               drmFree(r);
+               r = 0;
        }

 err_allocs:
        drmFree(U642VOID(ovr.format_type_ptr));
+       drmFree(U642VOID(ovr.format_modifier_ptr));

        return r;
 }

+drmModePlanePtr drmModeGetPlane2(int fd, uint32_t plane_id)
+{
+       drmModePlanePtr r = get_plane(DRM_IOCTL_MODE_GETPLANE2, fd, plane_id);
+
+       if (r || errno != EINVAL)
+               return r;
+
+       return get_plane(DRM_IOCTL_MODE_GETPLANE, fd, plane_id);
+}
+
+drmModePlanePtr drmModeGetPlane(int fd, uint32_t plane_id)
+{
+       return get_plane(DRM_IOCTL_MODE_GETPLANE, fd, plane_id);
+}
+
 void drmModeFreePlane(drmModePlanePtr ptr)
 {
        if (!ptr)
                return;

        drmFree(ptr->formats);
+       drmFree(ptr->format_modifiers);
        drmFree(ptr);
 }

diff --git a/xf86drmMode.h b/xf86drmMode.h
index b684967..044f38e 100644
--- a/xf86drmMode.h
+++ b/xf86drmMode.h
@@ -328,6 +328,9 @@ typedef struct _drmModePlane {

        uint32_t possible_crtcs;
        uint32_t gamma_size;
+
+       uint32_t count_format_modifiers;
+       struct drm_format_modifier *format_modifiers;
 } drmModePlane, *drmModePlanePtr;

 typedef struct _drmModePlaneRes {
@@ -479,6 +482,7 @@ extern int drmModePageFlipTarget(int fd, uint32_t crtc_id, 
uint32_t fb_id,

 extern drmModePlaneResPtr drmModeGetPlaneResources(int fd);
 extern drmModePlanePtr drmModeGetPlane(int fd, uint32_t plane_id);
+extern drmModePlanePtr drmModeGetPlane2(int fd, uint32_t plane_id);
 extern int drmModeSetPlane(int fd, uint32_t plane_id, uint32_t crtc_id,
                           uint32_t fb_id, uint32_t flags,
                           int32_t crtc_x, int32_t crtc_y,
-- 
2.9.3

Reply via email to