Re: [PATCH 1/2] Add DRM_IOCTL_MODE_GETPLANE2 ioctl wrapper

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 16-12-20 16:13:32, Kristian H. Kristensen wrote:
From: "Kristian H. Kristensen" <hoegsberg@xxxxxxxxxxxx>

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@xxxxxxxxxxxx>

+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

_______________________________________________
dri-devel mailing list
dri-devel@xxxxxxxxxxxxxxxxxxxxx
https://lists.freedesktop.org/mailman/listinfo/dri-devel




[Index of Archives]     [Linux DRI Users]     [Linux Intel Graphics]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [XFree86]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux