diff mbox

[1/2] Add DRM_IOCTL_MODE_GETPLANE2 ioctl wrapper

Message ID 20161221001333.21941-1-hoegsberg@gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

Kristian Høgsberg Dec. 21, 2016, 12:13 a.m. UTC
From: "Kristian H. Kristensen" <hoegsberg@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(-)

Comments

Ben Widawsky Dec. 26, 2016, 4:21 p.m. UTC | #1
On 16-12-20 16:13:32, Kristian H. Kristensen wrote:
>From: "Kristian H. Kristensen" <hoegsberg@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);
>+}
>+

IMO, it should be up to the client to fallback to drmModeGetPlane if
DRM_IOCTL_MODE_GETPLANE2 doesn't exist. However, as long as the modifiers are
returned as 0, it should work fine.

Reviewed-by: Ben Widawsky <ben@bwidawsk.net>

>+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
>
diff mbox

Patch

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,